<script setup>
import { onMounted, reactive, ref, watch } from 'vue'
import NumberBox from './components/UniDigitalNumber/NumberBox.vue'

const score = ref(1000) // 积分

const stake = reactive({
  yingtao: 0,
  taozi: 0,
  pingguo: 0,
  boluo: 0,
  caomei: 0,
  huolongguo: 0,
  xigua: 0
})

let stakeTemp = {
  pingguo: 0,
  yingtao: 0,
  taozi: 0,
  boluo: 0,
  caomei: 0,
  huolongguo: 0,
  xigua: 0
}

watch(stake, () => {
  for (const key in stake) {
    if (!stake[key]) {
      stake[key] = 0
    }
  }
})

const prizeList = [
  {id: 0, ratio: 2, probability: 50, color: '#2f93ff', fruit: 'boluo'},
  {id: 1, ratio: 1, probability: 100, color: '#80ee48', fruit: 'pingguo'},
  {id: 2, ratio: 10, probability: 5, color: '#fa4141', fruit: 'xigua'},
  {id: 3, ratio: 1, probability: 100, color: '#80ee48', fruit: 'yingtao'},
  {id: 4, ratio: 2, probability: 50, color: '#2f93ff', fruit: 'caomei'},
  {id: 5, ratio: 1, probability: 100, color: '#80ee48', fruit: 'taozi'},
  {id: 6, ratio: 3, probability: 25, color: '#9C4CFDCD', fruit: 'huolongguo'},
  {id: 7, ratio: 1, probability: 100, color: '#80ee48', fruit: 'boluo'},
  {id: 8, ratio: 2, probability: 50, color: '#2f93ff', fruit: 'pingguo'},
  {id: 9, ratio: 1, probability: 100, color: '#80ee48', fruit: 'yingtao'},
  {id: 10, ratio: 5, probability: 10, color: '#ffcd13', fruit: 'xigua'},
  {id: 11, ratio: 1, probability: 100, color: '#80ee48', fruit: 'taozi'},
  {id: 12, ratio: 2, probability: 50, color: '#2f93ff', fruit: 'huolongguo'},
  {id: 13, ratio: 1, probability: 100, color: '#80ee48', fruit: 'yingtao'},
  {id: 14, ratio: 3, probability: 25, color: '#9C4CFDCD', fruit: 'caomei'},
  {id: 15, ratio: 1, probability: 50, color: '#80ee48', fruit: 'taozi'}
]
const prizeNumber = 3 // 每次中奖格子数量
let prizeIndex = [] // 中奖格子序号
const rotateTimes = 5 // 旋转圈数
let elDomList = [] // 奖品格子dom
const lightColor = '#FFFFE5E5' // 旋转时闪烁颜色
const maxRefreshRate = 30 // 最高刷新速度
const minRefreshRate = 200 // 最低刷新速度
let nowRefreshRate = 200 // 当前刷新速度

let rotateIng = false
function start() {
  if (rotateIng) {
    alert("请等待上一次结束！")
    return
  }
  let stakeScore = 0
  for (const k in stake) {
    stakeScore = stakeScore + stake[k]
  }
  if (stakeScore > score.value) {
    alert("押注分数不能超过您的得分")
  } else {
    rotateIng = true
    score.value = score.value - stakeScore
    Object.assign(stakeTemp, stake)
    getPrizeIndex()
    doRotate(0, 0)
  }
}

function doRotate(i, t) {
  let index = i
  let times = t
  setTimeout(() => {
    if (index === prizeList.length) {
      index = 0
      times++
    } else {
      for (let j = 0; j < elDomList.length; j++) {
        if (j === index) {
          elDomList[j].style.backgroundColor = lightColor
          elDomList[j].style.transition =  'none'
        } else {
          elDomList[j].style.backgroundColor = prizeList[j].color
          elDomList[j].style.transition =  'all 150ms'
        }
      }
      index++
      if ((rotateTimes - times) <= 1 && nowRefreshRate <= minRefreshRate) {
        nowRefreshRate = nowRefreshRate + 10
      } else {
        if (nowRefreshRate >= maxRefreshRate) {
          nowRefreshRate = nowRefreshRate - 10
        }
      }
    }
    if (times >= rotateTimes) {
      gotoPrize(Math.max(...prizeIndex))
    } else {
      doRotate(index, times)
    }
  }, nowRefreshRate)
}

function gotoPrize(maxIndex, nowIndex = 0) {
  setTimeout(() => {
    for (let i = 0; i < elDomList.length; i++) {
      elDomList[i].style.backgroundColor = prizeList[i].color
    }
    elDomList[nowIndex].style.backgroundColor = lightColor
    let newIndex = nowIndex + 1
    if (newIndex <= maxIndex) {
      gotoPrize(maxIndex, newIndex)
    } else {
      prizeTwinkle(5, 0)
      prizeSettlement()
    }
    let prizeLightArr = prizeIndex.filter(i => i < newIndex)
    prizeLightArr.forEach(i => {
      elDomList[i].style.backgroundColor = lightColor
    })
  }, 200)
}

function getPrizeIndex() {
  let number = prizeNumber
  let selectedPrizes = [];
  let totalProbability = prizeList.reduce((a, b) => a + b.probability, 0);

  while (number > 0) {
    let random = Math.random() * totalProbability;
    let currentProbability = 0;
    let currentPrize;
    for (let i = 0; i < prizeList.length; i++) {
      currentProbability += prizeList[i].probability;
      if (random < currentProbability) {
        currentPrize = prizeList[i];
        break;
      }
    }
    if (selectedPrizes.indexOf(currentPrize) === -1) {
      selectedPrizes.push(currentPrize);
      number--;
    } else {
      // 如果该奖品已经中奖，重新选择
      // eslint-disable-next-line no-constant-condition
      while (true) {
        random = Math.random() * totalProbability;
        currentProbability = 0;
        currentPrize = null;
        for (let i = 0; i < prizeList.length; i++) {
          currentProbability += prizeList[i].probability;
          if (random < currentProbability && selectedPrizes.indexOf(prizeList[i]) === -1) {
            currentPrize = prizeList[i];
            break;
          }
        }
        if (currentPrize !== null) {
          selectedPrizes.push(currentPrize);
          number--;
          break;
        }
      }
    }
  }

  prizeIndex = []
  selectedPrizes.forEach(e => {
    prizeIndex.push(e.id)
  })
}

function prizeTwinkle(maxNum, nowNum) {
  setTimeout(() => {
    prizeIndex.forEach(i => {
      elDomList[i].style.backgroundColor = nowNum % 2 === 1 ? lightColor : prizeList[i].color
    })
    if (maxNum >= nowNum) {
      prizeTwinkle(maxNum, nowNum + 1)
    } else {
      prizeIndex.forEach(i => {
        elDomList[i].style.backgroundColor = lightColor
      })
    }
  }, 200)
}

const getScore = ref(0)
function prizeSettlement() {
  getScore.value = 0
  prizeIndex.forEach(i => {
    getScore.value = getScore.value + prizeList[i].ratio*stakeTemp[prizeList[i].fruit]
  })
  score.value = score.value + getScore.value
  rotateIng = false
}

onMounted(() => {
  for (let i = 1; i <= prizeList.length; i++) {
    elDomList.push(document.querySelector(`.div${i}`))
  }
})

</script>

<template>
  <div class="hs-wrap">
    <div class="parent">
      <div v-for="(e, i) in prizeList" :key="e.id" class="hs-grid" :class="`div${i + 1}`" :style="`background-color: ${e.color}`">
        <img :alt="e.fruit" :src="`images/fruit/${e.fruit}.png`"/>
        <div class="hs-ratio" v-if="e.ratio > 1">X <span>{{ e.ratio }}</span></div>
      </div>
      <div class="div17 hs-center">
        <div class="hs-score">
          <number-box :num="score.toString()" :size="40" color="#000"/>
        </div>
        <div class="hs-result" v-if="!rotateIng">您获得了{{ getScore }}分</div>
        <div class="hs-start" @click="start">
          开始
        </div>
      </div>
    </div>
    <div class="hs-stake-box">
      <div v-for="(value, key) in stake" :key="key" class="hs-stake-item">
        <img :alt="key" :src="`images/fruit/${key}.png`"/>
        <input class="hs-stake-input" type="number" v-model="stake[key]">
      </div>
    </div>
  </div>
</template>

<style scoped>
.hs-wrap{
  background-color: rgba(0,0,0,0.2);
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
}
.parent {
  height: 750px;
  width: 1000px;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  grid-template-rows: repeat(5, 1fr);
  grid-column-gap: 5px;
  grid-row-gap: 5px;
  background-color: #c5fde0;
  position: absolute;
  left: 50%;
  top: 40%;
  transform: translate(-50%, -50%);
  border: 5px solid #c5fde0;
}

.div1 { grid-area: 1 / 1 / 2 / 2; }
.div2 { grid-area: 1 / 2 / 2 / 3; }
.div3 { grid-area: 1 / 3 / 2 / 4; }
.div4 { grid-area: 1 / 4 / 2 / 5; }
.div5 { grid-area: 1 / 5 / 2 / 6; }
.div6 { grid-area: 2 / 5 / 3 / 6; }
.div7 { grid-area: 3 / 5 / 4 / 6; }
.div8 { grid-area: 4 / 5 / 5 / 6; }
.div9 { grid-area: 5 / 5 / 6 / 6; }
.div10 { grid-area: 5 / 4 / 6 / 5; }
.div11 { grid-area: 5 / 3 / 6 / 4; }
.div12 { grid-area: 5 / 2 / 6 / 3; }
.div13 { grid-area: 5 / 1 / 6 / 2; }
.div14 { grid-area: 4 / 1 / 5 / 2; }
.div15 { grid-area: 3 / 1 / 4 / 2; }
.div16 { grid-area: 2 / 1 / 3 / 2; }
.div17 { grid-area: 2 / 2 / 5 / 5; }

.hs-grid{
  display: flex;
  justify-content: center;
  align-items: center;
}

.hs-center {
  height: 100%;
  width: 100%;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  grid-template-rows: repeat(6, 1fr);
  grid-column-gap: 0;
  grid-row-gap: 0;
}

.hs-ratio{
  color: #333;
  font-size: 18px;
  font-weight: bolder;
}

.hs-ratio span{
  font-size: 36px;
}

.hs-start {
  grid-area: 5 / 3 / 6 / 5;
  background-color: #43A817FF;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #c6ecfc;
  font-weight: bolder;
  font-size: 28px;
  cursor: pointer;
}
.hs-score {
  grid-area: 2 / 2 / 4 / 6;
  background-color: #dcdcdc;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  padding: 15px;
  box-sizing: border-box;
}
.hs-stake-box{
  display: flex;
  position: absolute;
  left: 50%;
  bottom: 50px;
  transform: translate(-50%, 0);
}
.hs-stake-item{
  height: 150px;
  width: 150px;
  background-color: #1A73E8;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 15px;
}
.hs-stake-input {
  width: 100px;
}
.hs-result{
  grid-area: 4 / 3 / 5 / 5;
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
